(function(){
    // 在定义函数或类时，如果遇到类型不确定时就可以用泛型

    // 语法：<T,P,R>
    // T表示泛型，P表示泛型，R表示泛型
    // 比any的好处是：可以类型检测

    function fn<T>(a:T):T{
        return a;
    }

    let result=fn(10);// 不指定泛型，TS会自动推断出泛型
    let result2=fn<string>('hello');// 指定泛型

    // 泛型可以同时指定多个
    function fn2<T,P>(a:T,b:P):T{
        console.log(b);
        return a;
    }

    let result3=fn2(10,'hello');// 不指定泛型，TS会自动推断出泛型
    let result4=fn2<string,number>('hello',10);// 指定泛型

    interface Inter{
        length:number;
    }

    function fn3<T extends Inter>(a:T):number{
        return a.length;
    }
    // 泛型约束
    fn3({length:10}); // 正确 因为{length:10}符合Inter接口
    // fn3(10); // 报错 因为number没有length属性
    fn3('hello'); // 正确 因为'hello'有length属性


    // 泛型约束类
    class MyClass<T>{
        name:T;
        constructor(name:T){
            this.name=name;
        }
    }
    const mc=new MyClass<string>('孙悟空');
    mc.name='猪八戒';

})()